package cn.com.chengmandian.bike.utils;

import cn.com.chengmandian.core.web.exceptions.BadResponseException;
import cn.com.chengmandian.core.web.pojo.AgentInfo;
import cn.hutool.core.map.MapUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipayEncrypt;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipaySystemOauthTokenRequest;
import com.alipay.api.response.AlipaySystemOauthTokenResponse;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.Map;

@Slf4j
public class AliMiniUtil {
    private static final String SYSTEM_OAUTH_TOKEN = "alipay_system_oauth_token_response";
    private final static String CHARSET = "UTF-8";
    private final static String SIGN_TYPE = "RSA2";

    private final static String SUCCESS_CODE = "10000";


    public static Map alipayLogin(String code, AgentInfo agentInfo) throws AlipayApiException {
        AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
        request.setGrantType("authorization_code");
        request.setCode(code);
        log.info("alipayLogin: AppId={}, AliPayPrivateKey={}, AliPayCertPath={}, AliPayPublicCertPath={}, AliPayRootCertPath={}",
                agentInfo.getAliMiniAppid(),
                agentInfo.getAliPayPrivateKey(),
                agentInfo.getAliPayCertPath(),
                agentInfo.getAliPayPublicCertPath(),
                agentInfo.getAliPayRootCertPath());
        AlipaySystemOauthTokenResponse response = AliPayUtil.getAlipayClient(agentInfo.getAliMiniAppid(),
                        agentInfo.getAliPayPrivateKey(),
                        agentInfo.getAliPayCertPath(),
                        agentInfo.getAliPayPublicCertPath(),
                        agentInfo.getAliPayRootCertPath()).certificateExecute(request);
        if (response.isSuccess()) {
            Map map = JSON.parseObject(response.getBody(), Map.class);
            Map responseParam = getMapValueToMap(map, SYSTEM_OAUTH_TOKEN);
            log.info("登录-验签响应:{}", JSONObject.toJSONString(responseParam));
            return responseParam;
        }
        log.error("登录-验签失败={}", response.getBody());
        return MapUtil.of();
    }
//
//    public static void main(String[] args) throws Exception {
//        phone("dapq/o7Yao99tnqXsqdYwaWA6Tv6GSPdJ6OpvfjSEmkYv8H1KlwDoXwOCncruQ0kEs6uLbWWW9q4jpNMbOpJzq8UTAuljXbwiA3oxpH7U8oFgAb9S9reYVBJmmEqnA60wGfyIr6mYvfepIiB2+lHZLQteE52v02KzRYhT+F/CK6zrj6xZ29EuZ5v67uo+x5BBhP8gUxndMEvkha7qkpSn9NzDKMPWGnycU4NimpEqnaHEI1BKX9ypMq3iXoPXJRFhehpCfBTDct7ENJVzD5wLWjbPKQtIW23/ANB5RIMaLVvHhxodpOukvzuCdkva8u0XcK29wCAGTrSXCMLKW64BJj0NqnVPOrAP7N+Wphg/4M=",
//                "kgFPrbIBKtOsu5lA8S3XtJuf091HTvFevz1RD/SJSqjiIsoVcIth+2fvLBe8gJsg5veGmdemK7tOZAiI/79T0ns3BOMNBXvuwq2HrCxSWIoopfNRit1UbhcINHddGCoIxlZ0Shzuhs9LNTJWiI0s1s7FGKiy7WNcESWqJhBnV1edrA4PaUXsut4xjN8LDlqlV+UTyrlIw9NUZzGPSTNZVBr1EzHyzuAx4NynMi6XABZFm0uHvlW4InLlmeY34swJIfo/ctoPtMKTh1lCG6sdWGybidujGn9D2K8Bq8t4FYpstQ2SCEYW42jjjZkRSf0AnW1ItJ9hus/NDDnnI4hp7A==",
//                "LNA+S9pAO22vnpTkDXqndw==",
//                "D:\\alipayCertPublicKey_RSA2.crt");
//    }

    public static String phone(String content, String sign, String aliMiniDecryptKey, String aliPayPublicCertPath) throws Exception {
        String encryptType = "AES";
        boolean signCheckPass = false;
        //验签
        try {
            signCheckPass = verification(content, sign, aliPayPublicCertPath);
        } catch (AlipayApiException e) {
            log.error("aliPhone 验签异常!", e);
            throw new Exception("验签失败" + e.getMessage());
        }
        if (!signCheckPass) {
            throw new Exception("验签失败");
        }
        //解密
        String plainData = null;
        try {
            plainData = AlipayEncrypt.decryptContent(content, encryptType, aliMiniDecryptKey, CHARSET);
        } catch (AlipayApiException e) {
            log.error("aliPhone 解密异常!", e);
            throw new Exception("解密异常");
        }
        JSONObject result = JSON.parseObject(plainData);
        if (!SUCCESS_CODE.equals(result.get("code").toString())) {
            log.error("content：{}", content);
            log.error("encryptType：{}", encryptType);
            log.error("aliMiniDecryptKey：{}", aliMiniDecryptKey);
            log.error("解密失败：{}", result.toJSONString());
            throw new BadResponseException("解密失败：" + result.getString("msg"));
        }
        return result.get("mobile").toString();
    }

    /**
     * @return boolean
     * @Description: 验签
     * @author wujiajun
     * @version [1.0, 2021-06-15]
     */
    public static boolean verification(String content, String sign, String aliPayPublicCertPath) throws AlipayApiException {
        String signContent = content;
        signContent = "\"" + signContent + "\"";
        String signVeriKey = AlipaySignature.getAlipayPublicKey(aliPayPublicCertPath);
        return AlipaySignature.rsaCheck(signContent, sign, signVeriKey, CHARSET, SIGN_TYPE);

    }

    public static Map getMapValueToMap(Map map, String key) {
        return JSON.parseObject(String.valueOf(map.get(key)), Map.class);
    }
}
